"""
Enrollment model module

Defines data models related to student course enrollment, including:
- Enrollment class: represents student course enrollment records
- Enrollment status management
"""

from typing import Dict, List, Optional, Any
from datetime import datetime
import json


class Enrollment:
    """Enrollment class - represents student course enrollment records"""
    
    def __init__(self, enrollment_id: str, student_id: str, course_id: str, 
                 status: str = "active"):
        """
        Initialize enrollment object
        
        Parameters:
            enrollment_id: unique enrollment record identifier
            student_id: student ID
            course_id: course ID
            status: enrollment status (active, dropped, completed)
        """
        self.enrollment_id = enrollment_id
        self.student_id = student_id
        self.course_id = course_id
        self.status = status  # active, dropped, completed
        self.enrolled_at = datetime.now()
        self.updated_at = datetime.now()
    
    def update_status(self, new_status: str) -> bool:
        """
        Update enrollment status
        
        Parameters:
            new_status: new status (active, dropped, completed)
            
        Returns:
            whether update was successful
        """
        if new_status not in ["active", "dropped", "completed"]:
            return False
        
        self.status = new_status
        self.updated_at = datetime.now()
        return True
    
    def is_active(self) -> bool:
        """
        Check if enrollment is active
        
        Returns:
            whether active
        """
        return self.status == "active"
    
    def is_dropped(self) -> bool:
        """
        Check if enrollment is dropped
        
        Returns:
            whether dropped
        """
        return self.status == "dropped"
    
    def is_completed(self) -> bool:
        """
        Check if enrollment is completed
        
        Returns:
            whether completed
        """
        return self.status == "completed"
    
    def to_dict(self) -> Dict[str, Any]:
        """
        Convert enrollment object to dictionary
        
        Returns:
            dictionary representation of enrollment data
        """
        return {
            "enrollment_id": self.enrollment_id,
            "student_id": self.student_id,
            "course_id": self.course_id,
            "status": self.status,
            "enrolled_at": self.enrolled_at.isoformat(),
            "updated_at": self.updated_at.isoformat()
        }
    
    @classmethod
    def from_dict(cls, data: Dict[str, Any]) -> 'Enrollment':
        """
        Create enrollment object from dictionary
        
        Parameters:
            data: dictionary representation of enrollment data
            
        Returns:
            enrollment object
        """
        enrollment = cls(
            enrollment_id=data["enrollment_id"],
            student_id=data["student_id"],
            course_id=data["course_id"],
            status=data.get("status", "active")
        )
        
        enrollment.enrolled_at = datetime.fromisoformat(data["enrolled_at"]) if data.get("enrolled_at") else datetime.now()
        enrollment.updated_at = datetime.fromisoformat(data["updated_at"]) if data.get("updated_at") else datetime.now()
        
        return enrollment
    
    def __str__(self) -> str:
        """
        String representation
        
        Returns:
            string representation of enrollment information
        """
        return f"{self.enrollment_id}: Student {self.student_id} enrolled in course {self.course_id} - {self.status}"
    
    def __repr__(self) -> str:
        """
        Detailed string representation
        
        Returns:
            string representation of enrollment details
        """
        return (f"Enrollment(enrollment_id='{self.enrollment_id}', "
                f"student_id='{self.student_id}', course_id='{self.course_id}', "
                f"status='{self.status}')")
